using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Threading;
using System.Net.Mail;

/// <summary>
///handleDataFromClient 的摘要说明
/// </summary>
public class handleDataFromClient
{
    public handleDataFromClient()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }

    // 字典，存放 每个文件夹 的同步信息
    public static Dictionary<string, Semaphore> globalFile = new Dictionary<string, Semaphore>();

    static public int handle(string valueIn, string username, string directory)
    {
        // 文件夹名字作为关键字
        string key = username + "/" + directory;
        string actionNow = "";
        try
        {
            if (valueIn == "")
            {
                throw new Exception("the parameter of \"valueIn\" is empty");
            }

            // 从字典中查找：文件夹 的同步信息 有没有建立，没有建立则先建立
            lock (globalFile)
            {
                if (!globalFile.ContainsKey(key))
                {
                    // 建立 文件夹 的同步信息
                    globalFile[key] = new Semaphore(1, 1);
                }
            }
            // 1个文件夹只允许1个线程进入，现在本线程进入，其他线程不能进入
            globalFile[key].WaitOne();
            LOG.writer("开始反序列化xml到内存: " + HttpContext.Current.Server.MapPath("") + "\\userdata\\" + username + "\\" + directory);
            Xmlserdeser xser = new Xmlserdeser(HttpContext.Current.Server.MapPath("") + "\\userdata\\", username, directory);
            page myPage = xser.Mpage;
            table tmpTable;
            row tmpRow;
            web tmpWeb;
            string tmpWebID;
            if (valueIn.IndexOf("action") == 2)//是json数据.
            {
                valueIn = valueIn.Replace("'", "\"");
                XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(valueIn), XmlDictionaryReaderQuotas.Max);
                XmlDocument doc = new XmlDocument();
                doc.Load(reader);
                XElement tmproot = XElement.Parse(doc.OuterXml);
                if (tmproot.ToString().IndexOf("SEARCHWEBTABLE") > -1)
                {
                    return 0;//如果是搜索数据，则不进行保存处理.
                }
                XElement tmpRowXE;
                string tmpValue = tmproot.Element("action").Value;
                if (tmpValue == "AddWeb")  //添加web
                {
                    actionNow = tmpValue;

                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    string rowID = tmproot.Element("data").Element("table").Element("row").Element("ID").Value;
                    string webID = tmproot.Element("data").Element("table").Element("row").Element("web").Element("ID").Value;
                    string index = tmproot.Element("data").Element("table").Element("row").Element("index").Value;
                    XElement webXE = tmproot.Element("data").Element("table").Element("row").Element("web");
                    tmpRowXE = tmproot.Element("data").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(tableID);
                    tmpRow = tmpTable.getRowByID(rowID);
                    int intIndex = Convert.ToInt16(index);
                    if (intIndex > tmpRow.Mrowwebs.Count)
                    {
                        intIndex = tmpRow.Mrowwebs.Count;
                    }
                    //向webs数组中插入此web
                    var tlist = tmpRow.Mrowwebs.Where(O => O.ID == webXE.Element("ID").Value).ToList();
                    if (tlist.Count < 1)
                    {
                        tmpRow.Mrowwebs.Insert(intIndex, new web(webXE.Element("ID").Value, webXE.Element("Name").Value, webXE.Element("Link").Value, webXE.Element("Note").Value, "", "", "", ""));
                    }
                    if (directory != "private")//不要收集隐私数据.
                    {
                        searchClass.gatherDataToDB(webXE.Element("Name").Value, webXE.Element("Link").Value, webXE.Element("Note").Value);
                    }
                }
                else if (tmpValue == "MoveWeb")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    string fromRowID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("ID").Value;
                    string fromWebID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("web").Element("ID").Value;
                    string toTableID = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;
                    string toRowID = tmproot.Element("data").Element("to").Element("table").Element("row").Element("ID").Value;
                    string index = tmproot.Element("data").Element("index").Value;
                    XElement webXE = tmproot.Element("data").Element("from").Element("table").Element("row").Element("web");
                    tmpRowXE = tmproot.Element("data").Element("from").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(fromTableID);
                    tmpRow = tmpTable.getRowByID(fromRowID);
                    tmpWeb = tmpRow.getWebByID(webXE.Element("ID").Value);
                    table toTable = myPage.getTableByID(toTableID);
                    row toRow = toTable.getRowByID(toRowID);
                    int i = tmpRow.Mrowwebs.IndexOf(tmpWeb);//原来web的位置.
                    int a = Convert.ToInt16(index);
                    toRow.Mrowwebs.Insert(a, tmpWeb);
                    if ((i > a) && (fromRowID == toRowID))//如果向左移动，插入后原tmpWeb的位置加1
                    {
                        i++;
                    }
                    tmpRow.Mrowwebs.RemoveAt(i);//删除原来的web
                }
                else if (tmpValue == "CopyWeb")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    string fromRowID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("ID").Value;
                    string fromWebID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("web").Element("ID").Value;
                    string toTableID = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;
                    string toRowID = tmproot.Element("data").Element("to").Element("table").Element("row").Element("ID").Value;
                    string toWebID = tmproot.Element("data").Element("to").Element("table").Element("row").Element("web").Element("ID").Value;
                    string index = tmproot.Element("data").Element("index").Value;
                    XElement webXE = tmproot.Element("data").Element("from").Element("table").Element("row").Element("web");
                    tmpRowXE = tmproot.Element("data").Element("from").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(fromTableID);
                    tmpRow = tmpTable.getRowByID(fromRowID);
                    tmpWeb = tmpRow.getWebByID(webXE.Element("ID").Value);
                    table toTable = myPage.getTableByID(toTableID);
                    row toRow = toTable.getRowByID(toRowID);
                    if (toRow.Mrowwebs.Count == 0)
                    {
                        toRow.Mrowwebs.Add(new web(toWebID, tmpWeb.Name, tmpWeb.Link, tmpWeb.Note, "", "", "", ""));
                    }
                    else
                    {
                        //向webs数组中插入此web
                        toRow.Mrowwebs.Insert(Convert.ToInt16(index), new web(toWebID, tmpWeb.Name, tmpWeb.Link, tmpWeb.Note, "", "", "", ""));
                    }
                }
                else if (tmpValue == "UpdateWeb")//修改web数据
                {
                    actionNow = tmpValue;
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    string rowID = tmproot.Element("data").Element("table").Element("row").Element("ID").Value;
                    string webID = tmproot.Element("data").Element("table").Element("row").Element("web").Element("ID").Value;
                    XElement webXE = tmproot.Element("data").Element("table").Element("row").Element("web");
                    tmpRowXE = tmproot.Element("data").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(tableID);
                    tmpRow = tmpTable.getRowByID(rowID);
                    XElement tmpWebXe = tmpRowXE.Element("web");
                    tmpWeb = tmpRow.getWebByID(webID);
                    tmpWeb.Name = tmpWebXe.Element("Name").Value;
                    tmpWeb.Link = tmpWebXe.Element("Link").Value;
                    tmpWeb.Note = tmpWebXe.Element("Note").Value;
                }
                else if (tmpValue == "DeleteWeb")
                {
                    tmpRowXE = tmproot.Element("data").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(tmproot.Element("data").Element("table").Element("ID").Value);
                    tmpRow = tmpTable.getRowByID(tmpRowXE.Element("ID").Value);//++
                    tmpWebID = tmpRowXE.Element("web").Element("ID").Value;
                    tmpRow.Mrowwebs.Remove(tmpRow.getWebByID(tmpWebID));
                }
                else if (tmpValue == "numDisFirst")//改变第一个显示的序号
                {
                    tmpRowXE = tmproot.Element("data").Element("table").Element("row");
                    tmpRow = myPage.getTableByID(tmproot.Element("data").Element("table").Element("ID").Value).getRowByID(tmpRowXE.Element("ID").Value);//++
                    tmpRow.NumDisFirst = tmpRowXE.Element("numDisFirst").Value;
                }
                else if (tmpValue == "AddRow")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    XElement rowXE = tmproot.Element("data").Element("table").Element("row");
                    row newRow = new row(rowXE.Element("ID").Value, rowXE.Element("CateName").Value, "0");
                    XElement webXE = tmproot.Element("data").Element("table").Element("row").Element("web");
                    tmpRowXE = tmproot.Element("data").Element("table").Element("row");
                    tmpTable = myPage.getTableByID(tableID);
                    tmpTable.Mrows.Add(newRow);
                }
                else if (tmpValue == "MoveRow")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    string fromRowID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("ID").Value;
                    string toTableID = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;
                    tmpRowXE = tmproot.Element("data").Element("from").Element("table").Element("row");
                    string index = tmproot.Element("data").Element("index").Value;
                    tmpTable = myPage.getTableByID(fromTableID);
                    tmpRow = tmpTable.getRowByID(fromRowID);
                    int i = tmpTable.Mrows.IndexOf(tmpRow);
                    int a = Convert.ToInt16(index);
                    table toTable = myPage.getTableByID(toTableID);
                    toTable.Mrows.Insert(a, tmpRow);//移到新的位置.
                    if ((i > a) && (fromTableID == toTableID))//如果向上移动，插入后原tmpRow的位置加1
                    {
                        i++;
                    }
                    tmpTable.Mrows.RemoveAt(i);//删除原来的webRow
                }
                else if (tmpValue == "CopyRow")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    string fromRowID = tmproot.Element("data").Element("from").Element("table").Element("row").Element("ID").Value;
                    string toTableID = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;
                    tmpRowXE = tmproot.Element("data").Element("from").Element("table").Element("row");
                    string index = tmproot.Element("data").Element("index").Value;
                    tmpTable = myPage.getTableByID(fromTableID);
                    tmpRow = tmpTable.getRowByID(fromRowID);
                    table toTable = myPage.getTableByID(toTableID);
                    row newRow = Xmlserdeser.Clone(tmpRow) as row;
                    newRow.Id = tmproot.Element("data").Element("to").Element("table").Element("row").Element("ID").Value;
                    toTable.Mrows.Insert(Convert.ToInt16(index), newRow);
                    for (int i = 0; i < newRow.Mrowwebs.Count; i++)
                    {
                        newRow.Mrowwebs[i].ID = tmproot.Element("data").Element("to").Element("table").Element("row").Element("web").Elements("item").ElementAt(i).Element("ID").Value;
                    }
                }
                else if (tmpValue == "DeleteRow")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    string rowID = tmproot.Element("data").Element("table").Element("row").Element("ID").Value;
                    tmpTable = myPage.getTableByID(tableID);
                    tmpRow = tmpTable.getRowByID(rowID);
                    tmpTable.Mrows.Remove(tmpRow);
                }
                else if (tmpValue == "UpdateRow")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    string rowID = tmproot.Element("data").Element("table").Element("row").Element("ID").Value;
                    tmpTable = myPage.getTableByID(tableID);
                    tmpRow = tmpTable.getRowByID(rowID);
                    tmpRow.Ct = tmproot.Element("data").Element("table").Element("row").Element("CateName").Value;
                }
                else if (tmpValue == "AddTable")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    string tableName = tmproot.Element("data").Element("table").Element("Name").Value;
                    int index = Convert.ToInt16(tmproot.Element("data").Element("index").Value);
                    myPage.Mtables.Insert(index, (new table(tableID, tableName, "")));
                }
                else if (tmpValue == "MoveTable")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    int index = Convert.ToInt16(tmproot.Element("data").Element("index").Value);
                    tmpTable = myPage.getTableByID(fromTableID);
                    int i = myPage.Mtables.IndexOf(tmpTable);
                    myPage.Mtables.Insert(index, tmpTable);//移到新的位置.
                    if (i > index)//如果向上移动，插入后原table的位置加1
                    {
                        i++;
                    }
                    myPage.Mtables.RemoveAt(i);//删除原来的table
                }
                else if (tmpValue == "CopyTable")
                {
                    string fromTableID = tmproot.Element("data").Element("from").Element("table").Element("ID").Value;
                    string toTableID = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;
                    int index = Convert.ToInt16(tmproot.Element("data").Element("index").Value);
                    tmpTable = Xmlserdeser.Clone(myPage.getTableByID(fromTableID)) as table;
                    myPage.Mtables.Insert(index, tmpTable);
                    XElement tmpRowEx = tmproot.Element("data").Element("to").Element("table").Element("row");
                    myPage.Mtables[index].Id = tmproot.Element("data").Element("to").Element("table").Element("ID").Value;

                    for (int i = 0; i < tmpRowEx.Elements("item").Count(); i++)
                    {
                        row newRow = myPage.Mtables[index].Mrows[i];
                        newRow.Id = tmpRowEx.Elements("item").ElementAt(i).Element("ID").Value;
                        for (int k = 0; k < newRow.Mrowwebs.Count; k++)
                        {
                            newRow.Mrowwebs[k].ID = tmpRowEx.Elements("item").ElementAt(i).Element("web").Elements("item").ElementAt(k).Element("ID").Value;
                        }
                    }
                }
                else if (tmpValue == "DeleteTable")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    tmpTable = myPage.getTableByID(tableID);
                    myPage.Mtables.Remove(tmpTable);
                }
                else if (tmpValue == "UpdateTable")
                {
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    tmpTable = myPage.getTableByID(tableID);
                    tmpTable.Name = tmproot.Element("data").Element("table").Element("Name").Value;
                }
                else if (tmpValue == "SetHeadColor")
                {//set the headColor of the current table.
                    string tableID = tmproot.Element("data").Element("table").Element("ID").Value;
                    tmpTable = myPage.getTableByID(tableID);
                    tmpTable.HeadColor = tmproot.Element("data").Element("table").Element("HeadColor").Value;
                }
                else if (tmpValue == "CopyApp")
                {
                    string type = tmproot.Element("app").Element("Type").Value;
                    if (type == "000000")//the type is Web.
                    {

                    }
                    else if (type == "000001")//the type is WebRow.
                    {
                        DateTime t = DateTime.Now;
                        string timeStamp = (((t.Hour * 60 + t.Minute) * 60 + t.Second) * 1000 + t.Millisecond).ToString();//有id相冲突的隐患.
                        XElement xrow = tmproot.Element("app").Element("data").Element("table").Element("row");
                        string tableID_from = tmproot.Element("app").Element("data").Element("table").Element("ID").Value;
                        string rowID_from = tmproot.Element("app").Element("data").Element("table").Element("row").Element("ID").Value;
                        string fromStr = tmproot.Element("from").Value;
                        int i = fromStr.IndexOf('/');
                        string username_a = fromStr.Substring(0, i);
                        string directory_a = fromStr.Substring(i + 1, fromStr.Length - i - 1);
                        Xmlserdeser xser_from = new Xmlserdeser(HttpContext.Current.Server.MapPath("") + "\\userdata\\", username_a, directory_a);
                        page page_from = xser_from.Mpage;
                        table tmpTable_from = page_from.getTableByID(tableID_from);
                        row tmpRow_from = tmpTable_from.getRowByID(rowID_from);
                        row tmprow = Xmlserdeser.Clone(tmpRow_from) as row;
                        tmprow.Id = timeStamp + "CATE";
                        Xmlserdeser xser_to = new Xmlserdeser(HttpContext.Current.Server.MapPath("") + "\\userdata\\", username, directory);
                        page page_to = xser_to.Mpage;
                        table table_to = page_to.Mtables.Find(x => x.Id == "000000000100TB");
                        if (null == table_to)
                        {
                            table_to = new table("000000000100TB", "New table", "");
                            page_to.Mtables.Add(table_to);
                        }
                        if (null == table_to.Mrows)
                        {
                            table_to.Mrows = new List<row>();
                        }
                        table_to.Mrows.Add(tmprow);
                        xser = xser_to;
                        myPage = page_to;
                    }
                    else if (type == "000002")//the type is WebTable.
                    {
                        DateTime t = DateTime.Now;
                        string timeStamp = (((t.Hour * 60 + t.Minute) * 60 + t.Second) * 1000 + t.Millisecond).ToString();//有id相冲突的隐患.
                        XElement xrow = tmproot.Element("app").Element("data").Element("table").Element("row");
                        string tableID_from = tmproot.Element("app").Element("data").Element("table").Element("ID").Value;
                        string rowID_from = tmproot.Element("app").Element("data").Element("table").Element("row").Element("ID").Value;
                        string fromStr = tmproot.Element("from").Value;
                        int i = fromStr.IndexOf('/');
                        string username_a = fromStr.Substring(0, i);
                        string directory_a = fromStr.Substring(i + 1, fromStr.Length - i - 1);
                        Xmlserdeser xser_from = new Xmlserdeser(HttpContext.Current.Server.MapPath("") + "\\userdata\\", username_a, directory_a);
                        page page_from = xser_from.Mpage;
                        table tmpTable_from = page_from.getTableByID(tableID_from);
                        row tmpRow_from = tmpTable_from.getRowByID(rowID_from);
                        row tmprow = Xmlserdeser.Clone(tmpRow_from) as row;
                        tmprow.Id = timeStamp + "CATE";
                        Xmlserdeser xser_to = new Xmlserdeser(HttpContext.Current.Server.MapPath("") + "\\userdata\\", username, directory);
                        page page_to = xser_to.Mpage;
                        table table_to = page_to.Mtables.Find(x => x.Id == "000000000100TB");
                        if (null == table_to)
                        {
                            table_to = new table("000000000100TB", "New table", "");
                            page_to.Mtables.Add(table_to);
                        }
                        if (null == table_to.Mrows)
                        {
                            table_to.Mrows = new List<row>();
                        }
                        table_to.Mrows.Add(tmprow);
                        xser = xser_to;
                        myPage = page_to;
                    }
                }
            }
            xser.write(myPage, xser.XMLFilename);
            xser.simplifyXmlandJSON();
            LOG.writer("actionNow: " + actionNow);
            if (actionNow == "AddWeb" || actionNow == "UpdateWeb")  //添加web
            {
                string currentDir = HttpContext.Current.Server.MapPath("") + @"\userdata\" + username + @"\";
                LOG.writer(currentDir + @"user.xml" + "已登录");
                user userInstance = new user(currentDir + @"user.xml");

                string tomail = "";//用户没有留注册Email，就设置为空串。
                string nickname = "";
                if (!string.IsNullOrEmpty(userInstance.Em))
                {
                    tomail = userInstance.Em;
                }
                if (!string.IsNullOrEmpty(userInstance.Us))
                {
                    nickname = userInstance.Us;
                }
                string subject = "";
                if (actionNow == "AddWeb")
                {
                    subject = "您好，增加了内容。";
                }
                else
                {
                    subject = "您好，修改了内容。";
                }
                if (!string.IsNullOrEmpty(tomail))
                {
                    LOG.writer("开始发送邮件：" + tomail);
                    StreamReader sr = new StreamReader(xser.XMLFilename);
                    String body = sr.ReadToEnd();
                    sr.Dispose();
                    SendMail(body, subject, tomail, nickname, "管理员");

                }
            }


            return 1;
        }
        catch (Exception ex)
        {
            LOG.writer(ex.ToString());
            throw ex;
        }
        finally
        {
            // 事情做完，1个文件夹只允许1个线程进入，现在本线程退出，其他线程随机选择1个进入
            globalFile[key].Release();
        }
    }

    static private int SendMail(string JsonValue, string Subject, string toMail, string toNickName, string fromMailNickName)
    {
        MailMessage myMessage = new MailMessage();
        myMessage.Subject = Subject;
        myMessage.Body = JsonValue;
        myMessage.From = new MailAddress("459281182@qq.com", fromMailNickName);
        myMessage.To.Add(new MailAddress(toMail, toNickName));

        SmtpClient mySmtpClient = new SmtpClient();
        mySmtpClient.Host = "smtp.qq.com";
        mySmtpClient.Port = 25;
        mySmtpClient.Credentials = new System.Net.NetworkCredential("459281182@qq.com", "kyrfmpgelpnfcbbf");

        //指定 SmtpClient 使用安全套接字层(SSL)加密连接
        mySmtpClient.EnableSsl = false;
        //设置证书处理——忽视证书问题,直接返回true
        //ServicePointManager.ServerCertificateValidationCallback =
        //    delegate (Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; };


        try
        {
            mySmtpClient.Send(myMessage);
        }
        catch (SmtpException ex)
        {
            LOG.writer(ex.ToString());
            LOG.writer("发送邮件失败：" + toMail);

            return 0;
        }
        LOG.writer("发送邮件成功：" + toMail);

        return 1;
    }
}
